package jp.sourceforge.akjrcp.ffmpeg;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class JpegPipeReader {
	public static Log log = LogFactory.getLog(JpegPipeReader.class);

	private InputStream inputStream;
	public static final int[] START_JPEG={0xff,0xd8};
	public static final int[] END_JPEG={0xff,0xd9};
	private boolean started=false;
	private boolean done=false;
	
	private int waitDone=0;
	public JpegPipeReader(){
	}
	
	public JpegPipeReader(InputStream input){
		this.inputStream=input;
	}
	private static final int checkSeparate[]={END_JPEG[0],END_JPEG[1],START_JPEG[0],START_JPEG[1]};
	ByteArrayOutputStream bout=new ByteArrayOutputStream(1024*256);
	public byte[] nextImage(){
		
		if(done){
			return null;//for final action.
		}
		
		bout.reset();
		
		if(started){
			bout.write(START_JPEG[0]);
			bout.write(START_JPEG[1]);
		}else{
			try {
				//check initial jpeg?
				
				int s1=inputStream.read();
				if(s1==-1){
					//log.infono more 1");
				}
				
				int s2=inputStream.read();
				if(s2==-1){
					//log.infono more 2");
				}
				
				
				if(s1==START_JPEG[0] && s2==START_JPEG[1]){
					//log.trace("ok header");
					bout.write(START_JPEG[0]);
					bout.write(START_JPEG[1]);
				started=true;	
				}else{
					log.info("not header");
				return null;
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		 int much_index=0;
		 int b=-1;
		

	
		
		try {
			while(!done){ //Never read after done. othersiwe freeze it.
				
				if((b=inputStream.read())==-1){
					if(much_index==2){
						log.info("#try to find header");
					}
					//pipe finished.
					break;
				}
				
				if(checkSeparate[much_index]==b){
					if(much_index==3){
						//JPEG separated FOOTER + HEADER
						started=true;
						break;
					}else{
						
						if(much_index<2){//don't write ,only footer write out.header.
							bout.write(b);
						}
						
						much_index++;
						if(much_index==2){//JPEG END.
							//if(FFMpegFLVFileEffector.count>819){
							//	log.infodone:"+done);
						//	}
							if(waitDone>0){
							try {
								Thread.sleep(waitDone);//wait for done 
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}
							}
							if(done){
						//		log.infoafter done action:"+bout.size());
								started=true;
								return bout.toByteArray(); //after finish 
							}
							/*
							if(FFMpegFLVFileEffector.count==820){
								log.info820:");
								b=-1;//for to finish.
								break;
							}*/
						}
						
						//if(FFMpegFLVFileEffector.count>819){
						//	log.infomuching:"+much_index);
						//}
					}
				}else{
					bout.write(b);
					much_index=0;//not much.
				}
			}
			//finished.
			if(much_index==2 && b==-1){
				log.info("guess finish jpeg");
				started=false;
			}
			//after finished.
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		if(bout.toByteArray().length==0){
			return null;
		}else{
			return bout.toByteArray();
		}
	}
	
	public void close() throws IOException{
		if(inputStream!=null){
			inputStream.close();
		}
	}

	public boolean isDone() {
		return done;
	}

	public void setDone(boolean done) {
		this.done = done;
	}

	public InputStream getInputStream() {
		return inputStream;
	}

	public void setInputStream(InputStream inputStream) {
		this.inputStream = inputStream;
	}

	public int getWaitDone() {
		return waitDone;
	}

	public void setWaitDone(int waitDone) {
		this.waitDone = waitDone;
	}
}
